package com.lean.android.ad.core.splash

import android.app.Activity
import android.view.ViewGroup
import androidx.annotation.RestrictTo
import com.bytedance.sdk.openadsdk.AdSlot
import com.bytedance.sdk.openadsdk.CSJAdError
import com.bytedance.sdk.openadsdk.CSJSplashAd
import com.bytedance.sdk.openadsdk.TTAdNative.CSJSplashAdListener
import com.bytedance.sdk.openadsdk.TTAdSdk
import com.bytedance.sdk.openadsdk.mediation.ad.MediationAdSlot
import com.lean.android.ad.core.AdLoadState
import com.lean.android.ad.core.AdLoader
import com.lean.android.ad.core.AdSdk
import com.lean.android.ad.core.ErrorCode
import com.lean.android.ad.repository.ReportHelper
import com.lean.android.ad.repository.ReportHelper.toCpmInt
import com.lean.android.ad.utils.AdLog
import com.lean.android.ad.utils.DisplayHelper
import java.util.UUID
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

@RestrictTo(RestrictTo.Scope.LIBRARY)
class SplashAdLoader(private val isColdLaunch: Boolean, private val adContainer: ViewGroup) :
    AdLoader {

    companion object {
        private fun createAdSlot(width: Int, height: Int): AdSlot {
            val splashWidthDp = DisplayHelper.pxToDp(width)
            val screenHeightDp = DisplayHelper.pxToDp(height)

            val splashHeightDp: Float = screenHeightDp.toFloat()

            return AdSlot.Builder().setCodeId(AdSdk.getAdConfig().adParamsProvider.getSplashAdId())
                .setExpressViewAcceptedSize(splashWidthDp.toFloat(), splashHeightDp) // 单位是dp
                .setImageAcceptedSize(width, height) // 单位是px
                .setMediationAdSlot(
                    MediationAdSlot.Builder().setSplashShakeButton(true)
                        .setSplashPreLoad(false)//开屏gdt开屏广告预加载
                        .setMuted(false) //声音开启
                        .setVolume(1f)//admob 声音配置，与setMuted配合使用
                        .setBidNotify(true).build()
                ).build()
        }


    }

    override suspend fun load(
        activity: Activity
    ): AdLoadState {
        return suspendCoroutine { coroutine ->
            val requestId = UUID.randomUUID().toString()
            AdLog.d(AdLog.AdSplashLoadTag, "SplashAd start to load requestId $requestId")
            val nativeLoader = TTAdSdk.getAdManager().createAdNative(activity)
            adContainer.post {
                val containerWidth = adContainer.width
                val containerHeight = adContainer.height
                val adWidth = if (containerWidth == 0) {
                    DisplayHelper.getScreenWidth(activity)
                } else {
                    containerWidth
                }
                val adHeight = if (containerHeight == 0) {
                    DisplayHelper.getScreenHeight(activity) + DisplayHelper.getStatusBarHeight(
                        activity
                    )
                } else {
                    containerHeight
                }

                val slot = createAdSlot(adWidth, adHeight)
                nativeLoader.loadSplashAd(slot, object : CSJSplashAdListener {
                    override fun onSplashLoadSuccess(csjSplashAd: CSJSplashAd) {
                        AdLog.d(
                            AdLog.AdSplashLoadTag,
                            "SplashAd load success, requestId $requestId"
                        )
                    }

                    override fun onSplashLoadFail(error: CSJAdError) {
                        AdLog.e(
                            AdLog.AdSplashLoadTag,
                            "SplashAd load failed , requestId $requestId, code ${error.code}, message, ${error.msg}"
                        )

                        ReportHelper.reportAdEvent(
                            requestId = requestId,
                            eventType = ReportHelper.AdEventType.AdError,
                            adPosition = if (isColdLaunch) ReportHelper.AdPositionType.Splash else ReportHelper.AdPositionType.ReSplash,
                            errorCode = error.code.toString()
                        )

                        coroutine.resume(AdLoadState.Error(ErrorCode.ErrorAdLoadFailed, error.msg))

                    }

                    override fun onSplashRenderSuccess(csjSplashAd: CSJSplashAd) {
                        if (AdSdk.isBlack()) {
                            AdLog.e(
                                AdLog.AdSplashLoadTag,
                                "SplashAd in black list , requestId $requestId"
                            )
                            coroutine.resume(
                                AdLoadState.Error(
                                    ErrorCode.ErrorAdLoadFailed,
                                    "黑名单命中"
                                )
                            )
                        } else {
                            AdLog.d(AdLog.AdSplashLoadTag, "SplashAd load success.")
                            csjSplashAd.mediationManager?.bestEcpm?.also { cpmInfo ->
                                val cpm = cpmInfo.ecpm.toCpmInt()
                                ReportHelper.reportAdEvent(
                                    requestId = requestId,
                                    eventType = ReportHelper.AdEventType.AdLoaded,
                                    platformId = cpmInfo.sdkName.orEmpty(),
                                    adPosition = if (isColdLaunch) ReportHelper.AdPositionType.Splash else ReportHelper.AdPositionType.ReSplash,
                                    cpm = cpm
                                )
                            }
                            coroutine.resume(
                                AdLoadState.Success(
                                    SplashAd(
                                        csjSplashAd, requestId, isColdLaunch
                                    )
                                )
                            )
                        }

                    }

                    override fun onSplashRenderFail(csjSplashAd: CSJSplashAd, error: CSJAdError) {
                        AdLog.e(
                            AdLog.AdLoadTag,
                            "SplashAd render failed , requestId $requestId, code ${error.code}, message, ${error.msg}"
                        )
                    }
                }, 3500)
            }

        }

    }
}